﻿/*
 * Copyright (c) 2025 粤港澳大湾区（广东）国创中心
 *
 * This file is a part of NctiCAEPre.
 *
 * NctiCAEPre is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 *
 */

#ifndef UIOption_H
#define UIOption_H
#pragma once

#include "dcl_ncti_uioption.h"

#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace nlohmann::literals;

#include <type_traits>
#include <tuple>

#include <QString>
#include <QObject>
#include <QMetaObject>
#include <QDebug>

namespace NCTI {
    
/**
 * @brief UI页面类型枚举
 * @details 定义了各种UI页面的类型，用于区分不同的功能模块
 */
enum UIPageType {
    UI_FILE,              ///< 文件页面
    UI_GENERAL,           ///< 常规页面
    UI_SKETCH,            ///< 草图页面
    UI_GEOMETRY,          ///< 几何页面
    UI_AI,                ///< AI页面
    UI_SIMULATION,        ///< 仿真页面
    UI_CUSTOM,            ///< 自定义页面
    UI_INVALID_PAGE = -1, ///< 无效分类页
};

/**
 * @brief UI页面类型与JSON序列化映射
 */
NLOHMANN_JSON_SERIALIZE_ENUM(UIPageType,
                             {
                                 {UI_INVALID_PAGE, nullptr},
                                 {UI_FILE, "file"},
                                 {UI_GENERAL, "general"},
                                 {UI_SKETCH, "sketch"},
                                 {UI_GEOMETRY, "geometry"},
                                 {UI_AI, "ai"},
                                 {UI_SIMULATION, "simulation"},
                                 {UI_CUSTOM, "custom"},
                             })

/**
 * @brief UI动作结构体
 * @details 定义了UI动作的相关属性，如名称、图标、槽函数等
 */
class UIAction
{
public:
    int index = -1;               ///< 显示索引
    std::string name;             ///< 节点名称
    std::string object_name;      ///< 对象名称
    std::string icon_path;        ///< 节点图标路径
    std::string slot_name;        ///< 槽函数名称
    std::string short_cut;        ///< 快捷键
    int width = 0;                ///< 显示最小宽度
    std::string pystring;         ///< python脚本
    std::vector<UIAction> vChild; ///< 子节点列表

public:
    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UIAction,
                                   index,
                                   name,
                                   object_name,
                                   icon_path,
                                   slot_name,
                                   short_cut,
                                   width,
                                   pystring,
                                   vChild);
};

/**
 * @brief UI组项结构体
 * @details 定义了UI组项的相关属性
 */
class UIGroupItem
{
public:
    std::string name;        ///< 动作名称
    std::string object_name; ///< 对象名称
    std::string icon_path;   ///< 图标路径
    std::string slot_name;   ///< 槽函数名称

public:
    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UIGroupItem, name, object_name, icon_path, slot_name);
};

/**
 * @brief UI组结构体
 * @details 定义了UI组的相关属性
 */
class UIGroup
{
public:
    int index = -1;                   ///< 组索引
    std::string name;                 ///< 组名称
    std::string object_name;          ///< 对象名称
    std::vector<UIGroupItem> vChild;  ///< 子项列表

public:
    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UIGroup, index, name, object_name, vChild);
};

/**
 * @brief UI动作组项结构体
 * @details 定义了UI动作组项的相关属性
 */
class UIActionGroupItem
{
public:
    int row    = -1;         ///< 行数
    int column = -1;         ///< 列数
    std::string name;        ///< 动作名称
    std::string object_name; ///< 对象名称
    std::string slot_name;   ///< 槽函数名称

public:
    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UIActionGroupItem, row, column, name, object_name, slot_name);
};

/**
 * @brief UI动作组结构体
 * @details 定义了UI动作组的相关属性
 */
class UIActionGroup
{
public:
    int index  = -1;                    ///< 动作组索引
    int row    = -1;                    ///< 总行数
    int column = -1;                    ///< 总列数
    std::string frame_object_name;      ///< 对象名称
    std::string name;                   ///< 动作名称
    std::string object_name;            ///< 对象名称
    std::string icon_path;              ///< 图标路径
    std::string group_type;             ///< 分组类型check_box、radio_button
    std::vector<UIActionGroupItem> vChild; ///< 子项列表

public:
    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UIActionGroup,
                                   index,
                                   row,
                                   column,
                                   frame_object_name,
                                   name,
                                   object_name,
                                   icon_path,
                                   group_type,
                                   vChild);
};

/**
 * @brief UI设置结构体
 * @details 定义了UI设置的相关属性
 */
class UISetting
{
public:
    std::string name;               ///< 设置名称
    std::string object_name;        ///< 对象名称
    std::string icon_path;          ///< 图标路径
    std::vector<UISetting> vChild;  ///< 子项列表

public:
    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UISetting, name, object_name, icon_path, vChild);
};

/**
 * @brief UI面板结构体
 * @details 定义了UI面板的相关属性
 */
class UIPanel
{
public:
    int index = -1;                           ///< 面板索引
    std::string name;                         ///< 面板名称
    std::string object_name;                  ///< 对象名称
    std::vector<UIAction> actions;            ///< 动作列表
    std::vector<UIGroup> groups;              ///< 组列表
    std::vector<UIActionGroup> action_groups; ///< 动作组列表

    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UIPanel, index, name, object_name, actions, groups, action_groups);
};

/**
 * @brief UI页面结构体
 * @details 定义了UI页面的相关属性
 */
class UIPage
{
public:
    std::string object_name;        ///< 对象名称
    std::vector<UIPanel> panels;    ///< 面板列表

    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UIPage, object_name, panels);
};

/**
 * @brief UI标签页详情结构体
 * @details 定义了UI标签页的详细信息
 */
class UITabDetail
{
public:
    int index = -1;          ///< 排序索引
    std::string name;        ///< Tab名称
    std::string object_name; ///< 对象名称
    bool show = true;        ///< 是否显示

    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UITabDetail, index, name, object_name, show);
};

/**
 * @brief UI功能区结构体
 * @details 定义了UI功能区的相关属性
 */
class UIRibbon
{
public:
    std::string logo;              ///< 程序图标
    std::string title;             ///< 程序标题
    std::string version;           ///< 配置版本
    std::vector<UITabDetail> tabs; ///< 分类页

    /**
     * @brief 定义JSON序列化相关宏
     */
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(UIRibbon, logo, title, version, tabs);
};

/**
 * @brief UI选项类型枚举
 * @details 定义了系统和用户两种UI选项类型
 */
enum class UIOptionType { 
    System, ///< 系统类型
    User    ///< 用户类型
};

/**
 * @brief UI选项类
 * @details 负责加载和管理UI选项配置
 */
class NCTI_UIOPTION UIOption
{
public:
    /**
     * @brief 获取单例实例
     * @return UIOption的引用
     */
    static UIOption& GetInst();

    /**
     * @brief 加载UI选项
     * @return true表示成功，false表示失败
     */
    bool LoadUIOption();
    
    /**
     * @brief 加载UI页面
     * @param type UI选项类型
     * @param objectName 对象名称
     * @return UIPage对象
     */
    UIPage LoadUIPage(UIOptionType type, const std::string& objectName);

    /**
     * @brief 获取Logo路径
     * @return Logo路径字符串
     */
    QString GetLogo();
    
    /**
     * @brief 获取标题
     * @return 标题字符串
     */
    QString GetTitle();
    
    /**
     * @brief 获取版本
     * @return 版本字符串
     */
    QString GetVersion();
    
    /**
     * @brief 获取标签页名称
     * @param type UI页面类型
     * @return 标签页名称
     */
    std::string GetTabName(UIPageType type) const;

    /**
     * @brief 获取UI选项文件列表
     * @return 文件路径列表
     */
    QStringList GetUIOptionFiles();
    
    /**
     * @brief 获取UI功能区配置
     * @return UIRibbon对象
     */
    UIRibbon GetUIRibbon() const;
    
    /**
     * @brief 获取标签页列表
     * @param type UI选项类型
     * @return UITabDetail列表
     */
    std::vector<UITabDetail> GetTabs(UIOptionType type);

    /**
     * @brief 保存UI选项
     * @param type UI选项类型
     * @param uiRibbon UIRibbon对象
     */
    void SaveUIOption(UIOptionType type, const UIRibbon& uiRibbon);
    
    /**
     * @brief 保存UI页面
     * @param type UI选项类型
     * @param vPage UIPage列表
     */
    void SaveUIPages(UIOptionType type, const std::vector<UIPage>& vPage);

private:
    /**
     * @brief 检查版本是否更新
     * @param version 版本字符串
     * @return true表示已更新，false表示未更新
     */
    bool isVersionUpdated(const std::string& version);
    
    /**
     * @brief 复制UI选项文件
     * @param src 源路径
     * @param dst 目标路径
     * @return true表示成功，false表示失败
     */
    bool copyUIOptionFiles(const QString& src, const QString& dst);
    
    /**
     * @brief 加载UI选项
     * @param jsonPath JSON文件路径
     * @return UIRibbon对象
     */
    UIRibbon loadUIOption(const std::wstring& jsonPath) const;
    
    /**
     * @brief 加载UI页面
     * @param jsonPath JSON文件路径
     * @return UIPage对象
     */
    UIPage loadUIPage(const std::wstring& jsonPath);
    
    /**
     * @brief 保存UI页面
     * @param type UI选项类型
     * @param uiPage UIPage对象
     */
    void saveUIPage(UIOptionType type, const UIPage& uiPage);
    
    /**
     * @brief 初始化默认UI选项
     */
    void initDefaultUIOption();
    
    /**
     * @brief 获取UI选项路径
     * @param type UI选项类型
     * @return 路径字符串
     */
    QString getUIOptionPath(UIOptionType type);
    
    /**
     * @brief 获取UI详情路径
     * @param type UI选项类型
     * @param objectName 对象名称
     * @return 路径字符串
     */
    QString getUIDetailPath(UIOptionType type, const std::string& objectName);
    
    /**
     * @brief 获取JSON路径
     * @param type UI选项类型
     * @param objectName 对象名称
     * @param bCheckExists 是否检查存在性
     * @return 宽字符串路径
     */
    std::wstring getJsonPath(UIOptionType type, const std::string& objectName, bool bCheckExists = true);
    
    /**
     * @brief 添加动作到面板
     * @param panel UIPanel引用
     * @param action UIAction引用
     */
    void addActionToPanel(UIPanel& panel, const UIAction& action);
    
    /**
     * @brief 添加动作到面板
     * @param panel UIPanel引用
     * @param action UIGroup引用
     */
    void addActionToPanel(UIPanel& panel, const UIGroup& action);
    
    /**
     * @brief 添加动作到面板
     * @param panel UIPanel引用
     * @param action UIActionGroup引用
     */
    void addActionToPanel(UIPanel& panel, const UIActionGroup& action);

private:
    /**
     * @brief 构造函数
     */
    UIOption();
    
    /**
     * @brief 析构函数
     */
    ~UIOption();
    
    UIRibbon mUIRibbon; ///< UIRibbon对象
};
} // namespace NCTI

#endif // !UIOption_H